//abstract定义抽象类，不能被new 实例化
abstract class Package {
  //构造方法
  constructor(public weight: number) {}
  //抽象方法--只能定义一种形式，不能创建实例
  abstract calculate(): number;
  //具体实现
  printPackage() {
    console.log(`包裹的重量是${this.weight}kg,运费为：${this.calculate()}元 `);
  }
}

//一个类class只能继承extends一个抽象类abstract class
class StandardPackage extends Package {
  //unitPrice这边必须写修饰符，否则会报错
  constructor(weight: number, public unitPrice: number) {
    super(weight);
  }
  // calculate()继承了抽象类，这边是给抽象方法一个具体实现
  calculate(): number {
    return this.weight * this.unitPrice; //unitPrice这边必须写修饰符，否则会报错
  }
}

class ExpressPackage extends Package {
  //unitPrice这边必须写修饰符，否则会报错
  constructor(
    weight: number,
    public unitPrice: number, //特快单价比普通要高的单价
    public additional: number //超出的重加收费
  ) {
    super(weight);
  }
  // calculate()继承了抽象类，这边是给抽象方法一个具体实现
  calculate(): number {
    if (this.weight > 10) {
      return 10 * this.unitPrice + (this.weight - 10) * this.additional;
    } else {
      return this.weight * this.unitPrice;
    }
  }
}

const s = new StandardPackage(10, 5);
s.printPackage(); //普通包裹的重量是10kg,运费为：50元
console.log(s.calculate()); //50

const e = new ExpressPackage(13, 8, 2);
e.printPackage(); //特快包裹的重量是13kg,运费为：86元
